using System;
using System.Collections;
using System.Collections.Generic;
using Unity.Collections;

// 二维原生数组
public struct Native2DArray<T> : IDisposable, IEnumerable<T> where T : unmanaged
{
    private NativeArray<T> _data; // 内部一维数组存储
    public int Width { get; private set; } // 宽度（X维度）
    public int Height { get; private set; } // 高度（Y维度）

    // 构造函数
    public Native2DArray(int width, int height, Allocator allocator)
    {
        Width = width;
        Height = height;
        _data = new NativeArray<T>(width * height, allocator);
    }

    // 二维索引访问器
    public T this[int x, int y]
    {
        get
        {
            CheckBounds(x, y);
            return _data[y * Width + x];
        }
        set
        {
            CheckBounds(x, y);
            _data[y * Width + x] = value;
        }
    }

    // 检查索引是否越界
    private void CheckBounds(int x, int y)
    {
        if (x < 0 || x >= Width || y < 0 || y >= Height)
        {
            throw new IndexOutOfRangeException($"索引 ({x}, {y}) 超出范围 [0..{Width - 1}, 0..{Height - 1}]");
        }
    }

    // 释放资源
    public void Dispose()
    {
        if (_data.IsCreated)
        {
            _data.Dispose();
        }
    }

    // 获取迭代器
    public IEnumerator<T> GetEnumerator()
    {
        return new Native2DArrayEnumerator<T>(this);
    }

    // 非泛型迭代器实现
    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    // 自定义枚举器
    private struct Native2DArrayEnumerator<T> : IEnumerator<T> where T : unmanaged
    {
        private readonly Native2DArray<T> _array;
        private int _currentIndex;

        public Native2DArrayEnumerator(Native2DArray<T> array)
        {
            _array = array;
            _currentIndex = -1; // 初始状态
            Current = default;
        }

        public T Current { get; private set; }

        object IEnumerator.Current => Current;

        public bool MoveNext()
        {
            _currentIndex++;
            if (_currentIndex < _array._data.Length)
            {
                Current = _array._data[_currentIndex];
                return true;
            }

            return false;
        }

        public void Reset()
        {
            _currentIndex = -1;
            Current = default;
        }

        // 结构体不需要显式释放资源
        public void Dispose()
        {
        }
    }

    // 按行获取枚举器（可选）
    public IEnumerable<T> GetRow(int y)
    {
        if (y < 0 || y >= Height)
            throw new ArgumentOutOfRangeException(nameof(y));

        for (int x = 0; x < Width; x++)
        {
            yield return this[x, y];
        }
    }

    // 按列获取枚举器（可选）
    public IEnumerable<T> GetColumn(int x)
    {
        if (x < 0 || x >= Width)
            throw new ArgumentOutOfRangeException(nameof(x));

        for (int y = 0; y < Height; y++)
        {
            yield return this[x, y];
        }
    }
}